package com.ybb.vue.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ybb.vue.common.R;
import com.ybb.vue.common.Result;
import com.ybb.vue.common.constant.Constant;
import com.ybb.vue.common.util.AntianaphylaxisUtils;
import com.ybb.vue.common.util.OperationRecordsUtils;
import com.ybb.vue.common.webSocket.WebSocket;
import com.ybb.vue.domain.dto.UpdateUserPasswordDto;
import com.ybb.vue.domain.dto.UserDto;
import com.ybb.vue.domain.dto.UserLoginDto;
import com.ybb.vue.entity.SysRole;
import com.ybb.vue.entity.SysUser;
import com.ybb.vue.entity.SysUserRole;
import com.ybb.vue.mapper.SysUserMapper;
import com.ybb.vue.service.SysRoleService;
import com.ybb.vue.service.SysUserRoleService;
import com.ybb.vue.service.SysUserService;
import com.ybb.vue.common.util.DateUtil;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.io.File;
import java.util.*;

@RestController
@RequestMapping("/user")
@CrossOrigin
public class SysUserController {

    @Autowired
    private SysUserService userService;

    @Autowired
    private SysUserMapper mapper;

    @Value("${avatarImagesFilePath}")
    private String avatarImagesFilePath;

    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private SysUserRoleService sysUserRoleService;

    /**
     * 新增数据
     * @param userDto
     * @return
     */
    @PostMapping
    @PreAuthorize("hasAuthority('system:user:add')"+"||"+"hasAuthority('system:user:edit')")
    public Result<?> save(@RequestBody @Valid UserDto userDto) {
       return userService.saveUser(userDto);
    }

    /**
     * 编辑
     * @param userDto
     * @return
     */
    @PutMapping
    @PreAuthorize("hasAuthority('system:user:add')"+"||"+"hasAuthority('system:user:edit')")
    public Result<?> update(@RequestBody @Valid UserDto userDto) {
        SysUser result = userService.getByUsername(userDto.getUsername());
        String phoneNumber = userDto.getPhonenumber();
        StringBuffer phoneNumberStringBuffer = new StringBuffer();
        // 若不带有*号
        if (!phoneNumber.contains("*")) {
            if (!phoneNumber.matches("^[\\d\\*]{7,12}$")) {
                return Result.error("-1", "手机号格式有误！");
            } else {
                phoneNumberStringBuffer.append(phoneNumber);
            }
        }else{
            // 替换前三位和后三位
            phoneNumberStringBuffer.append(result.getPhonenumber());
            phoneNumberStringBuffer.replace(0, 3, phoneNumber.substring(0, 3));
            phoneNumberStringBuffer.replace(8, 11, phoneNumber.substring(8, 11));
        }

        BeanUtils.copyProperties(userDto,result);
        result.setPhonenumber(new String(phoneNumberStringBuffer));

        // 操作记录
        String content = "操作了用户表，【编辑】了1条记录，记录id为：" + userDto.getId();
        OperationRecordsUtils.createOperationRecords(content);
        return Result.success(mapper.updateById(result));
    }

    /**
     * 删/批量删除
     * @param ids
     * @return
     */
    @Transactional
    @PreAuthorize("hasRole('ROLE_admin')")
    @PostMapping("/delete")
    public Result<?> update(@RequestBody String[] ids) {
        userService.removeByIds(Arrays.asList(ids));
        sysUserRoleService.remove(new QueryWrapper<SysUserRole>().in("user_id",Arrays.asList(ids)));

        // 操作记录
        String content = "操作了用户表，【删除】了"+Arrays.asList(ids).size()+"条记录，记录id为：" + ids;
        OperationRecordsUtils.createOperationRecords(content);
        return Result.success();
    }

    /**
     * 注册
     * @param user
     * @return
     */
    @PostMapping("/register")
    public Result<?> register(@RequestBody @Valid UserLoginDto user) {
        SysUser result = userService.getByUsername(user.getUsername());
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        if (result != null) {
            return Result.error("-1","用户名已被注册");
        }
        if (user.getPassword() == null) {
            user.setPassword(bCryptPasswordEncoder.encode("123456"));
        }
        SysUser userInsert = new SysUser();
        user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
        BeanUtils.copyProperties(user,userInsert);
        mapper.insert(userInsert);
        return Result.success();
    }

    /**
     * 修改信息
     * @param userDto
     * @return
     */
    @PostMapping("/updateUserMessage")
    public Result<?> updateUserMessage(@RequestBody @Valid UserDto userDto) {
        SysUser result = userService.getByUsername(userDto.getUsername());
        if (result == null) {
            Result.error("-1", "未找到对应用户");
        }
        BeanUtils.copyProperties(userDto,result);
        mapper.updateById(result);
        return Result.success(result);
    }

    /**
     * 查询user列表
     * @param pageNum
     * @param pageSize
     * @param search
     * @return
     */
    @GetMapping("/userList")
    @PreAuthorize("hasAuthority('system:user:list')"+"||"+"hasAuthority('system:user:query')")
    public Result<?> userList (@RequestParam(defaultValue = "1") Integer pageNum,
                          @RequestParam(defaultValue = "10") Integer pageSize,
                          @RequestParam(defaultValue = "") String search) {
        Page<SysUser> result = mapper.selectPage(new Page<>(pageNum, pageSize), Wrappers.<SysUser>lambdaQuery().like(SysUser::getUsername, search));
        List<SysUser> userList = result.getRecords();
        for (SysUser user : userList) {
            List<SysRole> roleList = sysRoleService.list(new QueryWrapper<SysRole>().inSql("id", "select role_id from sys_user_role where user_id=" + user.getId()));
            user.setSysRoleList(roleList);
            // 手机号脱敏处理
            user.setPhonenumber(AntianaphylaxisUtils.antianaphylaxisUtil(3, 8, user.getPhonenumber()));
        }
        result.setRecords(userList);
        return Result.success(result);
    }

    /**
     * 获取所有用户，新增告警规则使用
     * @return
     */
    @GetMapping("/userListNoPages")
    public Result<?> userListNoPages(){
        List<SysUser> userList = mapper.selectList(new QueryWrapper<SysUser>().lambda().eq(SysUser::getStatus, "0"));
        return Result.success(userList);
    }

    /**
     * 修改密码
     * @param dto
     * @return
     */
    @PostMapping("/updatePassword")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public Result<?> updatePassword(@RequestBody @Valid UpdateUserPasswordDto dto) {
        return userService.updatePassword(dto);
    }

    /**
     * 上传用户头像图片
     * @param file
     * @return
     * @throws Exception
     */
    @RequestMapping("/uploadImage")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public Map<String,Object> uploadImage(MultipartFile file)throws Exception{
        Map<String,Object> resultMap=new HashMap<>();
        if(!file.isEmpty()){
            // 获取文件名
            String originalFilename = file.getOriginalFilename();
            String suffixName=originalFilename.substring(originalFilename.lastIndexOf("."));
            String newFileName= DateUtil.getCurrentDateStr()+suffixName;
            FileUtils.copyInputStreamToFile(file.getInputStream(),new File(avatarImagesFilePath+newFileName));
            resultMap.put("code",0);
            resultMap.put("msg","上传成功");
            Map<String,Object> dataMap=new HashMap<>();
            dataMap.put("title",newFileName);
            dataMap.put("src","/image/userAvatar/"+newFileName);
            resultMap.put("data",dataMap);
        }
        return resultMap;
    }

    /**
     * 修改用户头像
     * @param sysUser
     * @return
     */
    @RequestMapping("/updateAvatarImg")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public Result<?> updateAvatar(@RequestBody SysUser sysUser){
        SysUser currentUser = userService.getById(sysUser.getId());
        currentUser.setAvatar(sysUser.getAvatar());
        userService.updateById(currentUser);
        return Result.success();
    }

    /**
     * 重置密码
     * @param id
     * @return
     */
    @GetMapping("/resetPassword/{id}")
    @PreAuthorize("hasAuthority('system:user:resetPwd')")
    public R resetPassword(@PathVariable(value = "id")String id){
        SysUser sysUser = userService.getById(id);
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        sysUser.setPassword(bCryptPasswordEncoder.encode(Constant.DEFAULT_PASSWORD));
        userService.updateById(sysUser);

        // 操作记录
        String content = "操作了用户表，【重置密码】，记录id为：" + id;
        OperationRecordsUtils.createOperationRecords(content);
        return R.ok();
    }

    /**
     * 更新status状态
     * @param id
     * @param status
     * @return
     */
    @GetMapping("/updateStatus/{id}/status/{status}")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public R updateStatus(@PathVariable(value = "id")String id,@PathVariable(value = "status")String status){
        SysUser sysUser = userService.getById(id);
        sysUser.setStatus(status);
        userService.saveOrUpdate(sysUser);

        // 操作记录
        String content = "操作了用户表，【编辑账号状态】，记录id为：" + id;
        OperationRecordsUtils.createOperationRecords(content);
        return R.ok();
    }

    /**
     * 用户角色授权
     * @param userId
     * @param roleIds
     * @return
     */
    @Transactional
    @PostMapping("/grantRole/{userId}")
    @PreAuthorize("hasAuthority('system:user:role')")
    public R grantRole(@PathVariable("userId") String userId,@RequestBody Long[] roleIds){
        List<SysUserRole> userRoleList=new ArrayList<>();
        Arrays.stream(roleIds).forEach(r -> {
            SysUserRole sysUserRole = new SysUserRole();
            sysUserRole.setRoleId(r);
            sysUserRole.setUserId(userId);
            userRoleList.add(sysUserRole);
        });
        sysUserRoleService.remove(new QueryWrapper<SysUserRole>().eq("user_id",userId));
        sysUserRoleService.saveBatch(userRoleList);

        // 操作记录
        String content = "操作了用户表，【授权】，记录id为：" + userId;
        OperationRecordsUtils.createOperationRecords(content);
        return R.ok();
    }
}
